package ch.ethz.group3.myalbum.server.flickr;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;

import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.FlickrApi;
import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;

import ch.ethz.group3.myalbum.shared.AuthorizationModel;
import ch.ethz.group3.myalbum.shared.TokenModel;

import com.flickr4java.flickr.Flickr;
import com.flickr4java.flickr.FlickrException;
import com.flickr4java.flickr.REST;
import com.flickr4java.flickr.RequestContext;
import com.flickr4java.flickr.auth.Auth;
import com.flickr4java.flickr.auth.AuthInterface;
import com.flickr4java.flickr.auth.Permission;
import com.flickr4java.flickr.groups.Group;
import com.flickr4java.flickr.groups.GroupsInterface;
import com.flickr4java.flickr.photos.Photo;
import com.flickr4java.flickr.photos.PhotosInterface;
import com.flickr4java.flickr.photos.SearchParameters;
import com.flickr4java.flickr.photos.comments.Comment;
import com.flickr4java.flickr.photos.comments.CommentsInterface;
import com.flickr4java.flickr.util.IOUtilities;

public class FlickrDAO {

	private static String apiKey;
	private static String apiSecret;
	private static InputStream in = null;
	private static Properties properties = null;
	private Flickr f;
	private OAuthService service;

	static {
		try {
			in = FlickrDAO.class.getResourceAsStream("setup.properties");
			properties = new Properties();
			properties.load(in);
		} catch (Exception e) {
		} finally {
			IOUtilities.close(in);
		}

		apiKey = properties.getProperty("apiKey");
		apiSecret = properties.getProperty("secret");

		Flickr.debugRequest = false;
		Flickr.debugStream = false;
	}

	public FlickrDAO() {
		service = new ServiceBuilder().provider(FlickrApi.class).apiKey(apiKey)
				.apiSecret(apiSecret).build();
		f = new Flickr(apiKey, apiSecret, new REST());
	}

	public boolean isValidToken(TokenModel token) {
		RequestContext requestContext = RequestContext.getRequestContext();
		if (requestContext != null && token != null) {
			setContext(token);
			AuthInterface authInterface = f.getAuthInterface();
			try {
				Auth auth = authInterface.checkToken(token.getToken(),
						token.getSecret());
				if (auth == null)
					return false;
				else
					requestContext.setAuth(auth);
			} catch (FlickrException e) {
				return false;
			}
			return true;
		}
		return false;
	}

	public AuthorizationModel getAuthModel() {
		Token requestToken = service.getRequestToken();
		String authorizationUrl = service.getAuthorizationUrl(requestToken);
		authorizationUrl += "&perms=read";
		return new AuthorizationModel(authorizationUrl, new TokenModel(
				requestToken.getToken(), requestToken.getSecret()));
	}

	public TokenModel verify(TokenModel token, String verifierString) {
		Token requestToken = new Token(token.getToken(), token.getSecret());
		Verifier verifier = new Verifier(verifierString);
		Token accessToken = service.getAccessToken(requestToken, verifier);

		TokenModel authToken = new TokenModel(accessToken.getToken(),
				accessToken.getSecret());

		return authToken;
	}

	public Collection<Photo> getPhotosByTag(String tag, int pageLimit, int page,
			TokenModel token) throws FlickrException {

		SearchParameters params = new SearchParameters();
		params.setText(tag);

		return getPhotos(params, pageLimit, page, token);
	}

	public Collection<Photo> getPhotosByGroupId(String groupId, int pageLimit,
			int page, TokenModel token) throws FlickrException {

		SearchParameters params = new SearchParameters();
		params.setGroupId(groupId);

		return getPhotos(params, pageLimit, page, token);
	}

	private Collection<Photo> getPhotos(SearchParameters params, int pageLimit,
			int page, TokenModel token) throws FlickrException {
		Collection<Photo> result = new ArrayList<Photo>();
		PhotosInterface ff = f.getPhotosInterface();

		setContext(token);

		result = ff.search(params, pageLimit, page);
		
		Collection<Photo> infoPhotos = new ArrayList<Photo>();
		
		for (Photo g : result) {
			infoPhotos.add(ff.getInfo(g.getId(), token.getSecret()));
		}
		
		return infoPhotos;
	}

	private void setContext(TokenModel token) {
		RequestContext requestContext = RequestContext.getRequestContext();
		Auth auth = new Auth();
		auth.setToken(token.getToken());
		auth.setTokenSecret(token.getSecret());
		auth.setPermission(Permission.READ);
		requestContext.setAuth(auth);
	}

	public Collection<Group> getGroups(String tag, int pageLimit, int page,
			TokenModel token) throws FlickrException {
		Collection<Group> result = new ArrayList<Group>();

		GroupsInterface gi = f.getGroupsInterface();

		setContext(token);
		
		result = gi.search(tag, pageLimit, page);
		
		Collection<Group> infoGroup = new ArrayList<Group>();
		
		for (Group g : result) {
			infoGroup.add(gi.getInfo(g.getId()));
		}
		
		return infoGroup;
	}

	public Collection<Comment> getComments(String photoId, TokenModel token)
			throws FlickrException {

		f = new Flickr(apiKey, apiSecret, new REST());
		Collection<Comment> result = new ArrayList<Comment>();
		setContext(token);
		CommentsInterface ci = f.getCommentsInterface();

		result = ci.getList(photoId);
		return result;
	}

}
